package com.itaem.community.mybatisplus;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.itaem.community.core.entity.Entity;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * <p>项目名称: community </p>
 * <p>文件名称: CommunityCodeGenerator </p>
 * <p>描述: [类型描述] </p>
 * <p>创建时间: 2020/10/26 </p>
 * <p>作者信息: tomato</p>
 *
 * @author tomato
 * @version v1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ConfigurationProperties(prefix = "generator")
@Setter
@Getter
@SpringBootTest
class CommunityCodeGenerator {

    @Value("${spring.datasource.druid.url}")
    private String url;

    @Value("${spring.datasource.druid.username}")
    private String username;

    @Value("${spring.datasource.druid.password}")
    private String password;

    @Value("${spring.datasource.druid.driver-class-name}")
    private String driverName;

    private List<String> tables;
    private String project;
    private String entityName;
    private String mapperName;
    private String xmlName;
    private String serviceName;
    private String serviceImplName;
    private String controllerName;

    @Test
    void generateOne() {
        String module = "property_company_user";
        String author = "tomato";
        generate(module, author);
    }

    @Test
    void generateAll() {
        for (String table : tables) {
            generate(table, "tomato");
        }
    }

    @Test
    void testSplit() {
        System.out.println(Arrays.toString(project.split("\\.")));
        System.out.println(StringUtils.join(project.split("\\."), "/"));
    }

    private void generate(String module, String author) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        String camelModule = toCamel(module);

        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        globalConfig.setOutputDir(projectPath + "/src/main/java/");
        // 设置作者
        globalConfig.setAuthor(author);
        // 是否打开输出目录
        globalConfig.setOpen(false);
        // 加入swagger2注解
        globalConfig.setSwagger2(true);
        // 设置实体名后缀
        globalConfig.setEntityName("%s" + entityName);
        // 设置Mapper后缀
        globalConfig.setMapperName("%s" + mapperName);
        // 设置mapper.xml的文件名后缀
        globalConfig.setXmlName("%s" + xmlName);
        // 设置service的后缀
        globalConfig.setServiceName("%s" + serviceName);
        // 设置serviceimpl的后缀
        globalConfig.setServiceImplName("%s" + serviceImplName);
        // 设置Controller的后缀
        globalConfig.setControllerName("%s" + controllerName);
        // 设置主键类型
        globalConfig.setIdType(IdType.AUTO);
        mpg.setGlobalConfig(globalConfig);


        // 数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        // 设置数据库连接url
        dataSourceConfig.setUrl(url);
//        dataSourceConfig.setSchemaName("public");
        // 设置数据库类型
        dataSourceConfig.setDbType(DbType.MYSQL);
        // 设置驱动名
        dataSourceConfig.setDriverName(driverName);
        // 数据库登录账户名
        dataSourceConfig.setUsername(username);
        // 数据库登录密码
        dataSourceConfig.setPassword(password);
        mpg.setDataSource(dataSourceConfig);


        // 包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(camelModule);
        packageConfig.setParent(project);
        // 设置这个可以不在对应的包下生成xml，然后通过后面的自定义配置将mapper.xml集合到一起
        // packageConfig.setXml(null);
        mpg.setPackageInfo(packageConfig);


        // 自定义配置
        InjectionConfig config = new InjectionConfig() {
            @Override
            public void initMap() {

            }
        };

        // 自定义输出配置
        List<FileOutConfig> fileOutConfigList = new ArrayList<>();
        // 自定义配置会被优先输出
        fileOutConfigList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath
                        + "/src/main/resources/mapper/"
                        + camelModule
                        + StringPool.SLASH
                        + tableInfo.getMapperName()
                        + StringPool.DOT_XML;
            }
        });
        config.setFileOutConfigList(fileOutConfigList);
        mpg.setCfg(config);


        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        templateConfig.setController("/templates/controller.java.vm");
        mpg.setTemplateEngine(new VelocityTemplateEngine());
        mpg.setTemplate(templateConfig);


        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setSuperEntityClass(Entity.class);
        // 写于父类中的公共字段
        strategy.setSuperEntityColumns("id");
        strategy.setInclude(module);
        strategy.setControllerMappingHyphenStyle(true);
        mpg.setStrategy(strategy);
        mpg.execute();
    }

    private String toCamel(String s) {
        if (StringUtils.isEmpty(s) || StringUtils.indexOf(s, "_") == -1) {
            return s;
        }
        String[] parts = s.split("_");
        for (int i = 1; i < parts.length; i++) {
            parts[i] = StringUtils.capitalize(parts[i]);
        }
        return StringUtils.join(parts);
    }
}
